package com.only.common.util;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.only.common.exception.BizExceptionFactory;
import org.apache.commons.compress.utils.Lists;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * @author only
 * @date 2023/12/1
 * @description excel 工具类
 */
public class ExcelUtil {

    private static final Logger LOGGER = LoggerFactory.getLogger(ExcelUtil.class);

    /**
     * 当前工具类不可实例化
     */
    private ExcelUtil() {}

    /**
     * excel解析
     *
     * @param file 解析文件
     * @param clazz 接收转换类
     * @param headerLine 第几行作为表头
     * @return List<T> 返回 T 类型数据集合
     */
    public static <T> List<T> readExcel(MultipartFile file, Class<T> clazz, int headerLine) {
       return readExcel(file, clazz, headerLine,0);
    }

    /**
     * excel解析
     *
     * @param file 解析文件
     * @param clazz 接收转换类
     * @return List<T> 返回 T 类型数据集合
     */
    public static <T> List<T> readCsv(MultipartFile file, Class<T> clazz) {
        List<T> resultList = new ArrayList<>();
        try{
            EasyExcel.read(file.getInputStream(), clazz, new AnalysisEventListener<T>() {
                        @Override
                        public void invoke(T data, AnalysisContext context) {
                            resultList.add(data);
                        }

                        @Override
                        public void doAfterAllAnalysed(AnalysisContext context) {

                        }
                    })
                    .sheet()
                    .headRowNumber(1) //
                    .doRead();
        }catch (Exception e){
            LOGGER.error("解析csv文件失败！",e);
            throw BizExceptionFactory.badRequestException("解析csv文件失败！");
        }

        // 执行解析

        return resultList;
    }

    /**
     * excel 指定 sheet 页解析
     * @param file 解析文件
     * @param clazz 接收转换类
     * @param headerLine 第几行为表头
     * @param sheetIndex sheet索引
     * @return List<T> 返回 T 类型数据集合
     */
    public static <T> List<T> readExcel(MultipartFile file, Class<T> clazz, int headerLine, int sheetIndex) {

        try {
            return readExcel(file.getInputStream(), clazz, headerLine, sheetIndex);
        } catch (IOException e) {
            LOGGER.error("无法解析上传的文件: {}", e.getMessage(), e);
            throw BizExceptionFactory.systemExceptionWithDefaultMsg("无法解析上传的文件");
        }
    }


    /**
     * excel 指定 sheet 页解析（优化通用点，支持输入流）
     * @param is InputStream输入流
     * @param clazz 接收类
     * @param headerLine 第几行为表头
     * @param sheetIndex sheet索引
     * @return List<T> 返回 T 类型数据集合
     */
    public static <T> List<T> readExcel(InputStream is, Class<T> clazz, int headerLine, int sheetIndex) {
        List<T> resultList = Lists.newArrayList();

        EasyExcel.read(is, clazz, new AnalysisEventListener<T>() {
            @Override
            public void invoke(T data, AnalysisContext context) {
                resultList.add(data);
            }

            @Override
            public void doAfterAllAnalysed(AnalysisContext context) {

            }
        })
        .headRowNumber(headerLine)
        .sheet(sheetIndex)
        .doRead();

        return resultList;
    }

}
